package spe.ui.wizard;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import spe.ui.editor.SPEMEditorInput;

/**
 *	@author Dao Anh Vu
 *	@since 1.0 
 * 
 */
public class NewMethodLibraryWizard extends Wizard implements INewWizard {
	
	public static final String ID = NewMethodLibraryWizard.class.getName();
	
	private IStructuredSelection selection;
	private NewMethodLibraryWizardPage mainPage;
	private IProject project;
	private IFile modelFile = null;
	
	@Override
	public void addPages()	{	
		mainPage = new NewMethodLibraryWizardPage();
		mainPage.init(selection);
		addPage(mainPage);
	}
	
	@Override
	public void init(IWorkbench workbench, IStructuredSelection selection)	{
		this.selection = selection;  
		setWindowTitle("New Method Library");
		
		Object obj = selection.getFirstElement();
		if(obj instanceof IProject) {
			project = (IProject)obj;
			System.out.println(String.format("fullpath: %s",  project.getFullPath()));
		}
	}
	
	@Override
	public void createPageControls(Composite pageContainer)	{
		super.createPageControls(pageContainer);
	}

	@Override
	public boolean performFinish() {
		final IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		try {
			IFolder folder = mainPage.getMethodLibraryFolder();
			
			if(!folder.exists())
				folder.create(true, true, null);
			
			modelFile = folder.getFile("spe-model.xml");
			if(!modelFile.exists())
				modelFile.create(createInitialMethodLibrary(), true, null);
			else {
				try {
					DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
					TransformerFactory transformerFactory = TransformerFactory.newInstance();
					DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
					Document doc = builder.parse(modelFile.getContents());
					Element root = doc.getDocumentElement();
					Element libElement = doc.createElement("method-library");
					Node tabNode = doc.createTextNode("\t");
					
					libElement.setAttribute("name", mainPage.getMethodLibraryName());
					libElement.setAttribute("id", mainPage.getMethodLibraryName());
					root.appendChild(tabNode);
					root.appendChild(libElement);
					tabNode = doc.createTextNode("\n");
					root.appendChild(tabNode);
					
					StringWriter writer = new StringWriter();
					DOMSource domSource = new DOMSource(root);
					Transformer transformer = transformerFactory.newTransformer();
					StreamResult streamResult = new StreamResult(writer);
					transformer.transform(domSource, streamResult);
					
					modelFile.setContents(new ByteArrayInputStream(writer.toString().getBytes()), true, true, null);
					
				} catch (ParserConfigurationException e) {
					e.printStackTrace();
				} catch (SAXException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TransformerConfigurationException e) {
					e.printStackTrace();
				} catch (TransformerException e) {
					e.printStackTrace();
				}
			}
			
			IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() {
				
				@Override
				public void run(IProgressMonitor arg0) throws InvocationTargetException,
						InterruptedException {
					try{
						asynOpenEditor(modelFile, ww);
					}catch(PartInitException pe){
						pe.printStackTrace();
					}
				}
			};
			ww.run(false, false, runnableWithProgress);
			
			return true;
		} catch (CoreException e1) {
			e1.printStackTrace();
		}catch(InterruptedException ie){
			ie.printStackTrace();
		}catch(InvocationTargetException e){
			e.printStackTrace();
		}
		
		return false;
	}
	
	//will be called asynchronously
	private void asynOpenEditor(IFile file, IWorkbenchWindow ww)throws PartInitException, InterruptedException, InvocationTargetException{
		IWorkbenchPage activePage = ww.getActivePage();
		 SPEMEditorInput input = new SPEMEditorInput(file);
		//activePage.openEditor(input, SPEMGraphEditor.ID, false);
		activePage.openEditor(input, "spe.ui.editor.SPEMGraphEditor", false);
		BasicNewResourceWizard.selectAndReveal(modelFile, ww);
	}
	
	//manipulate with file
	private ByteArrayInputStream createInitialMethodLibrary()	{
		//String parName = mainPage.getMethodLibraryFolder().getName();
		String parName = mainPage.getMethodLibraryName();
		String processName = parName; //.substring(0, parName.indexOf(".par"));
		StringBuffer buffer = new StringBuffer();
		buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		buffer.append("\n");
		buffer.append("<spe-root xmlns:xml=\"http://www.w3.org/2001/XML\" project-name=\"" + project.getName() + "\">\n\t<method-library  name=\"" + processName + "\" id=\""+ processName +"\" ></method-library>\n</spe-root>");	
		return new ByteArrayInputStream(buffer.toString().getBytes());
	}
}
